package ci

import (
	"bytes"
	"context"
	"errors"
	"github.com/bndr/gojenkins"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"text/template"
)

type PipelineOptions struct {
	BuildEnv          string `json:"buildEnv"      mapstructure:"buildEnv"`
	Namespace         string `json:"namespace"      mapstructure:"namespace"`
	Credential        string `json:"credential"      mapstructure:"credential"`
	CodeBranch        string `json:"codeBranch"      mapstructure:"codeBranch"`
	ImageUrl          string `json:"imageUrl"      mapstructure:"imageUrl"`
	ImageProject      string `json:"imageProject"      mapstructure:"imageProject"`
	AppName           string `json:"appName"      mapstructure:"appName"`
	CodeRepo          string `json:"codeRepo"      mapstructure:"codeRepo"`
	Port              string `json:"port" mapstructure:"port"`
	Notify            string `json:"notify"      mapstructure:"notify"`
	ApolloConfigURL   string `json:"apolloConfigURL" mapstructure:"apolloConfigURL"`
	ApolloServiceName string `json:"apolloServiceName" mapstructure:"apolloServiceName"`
	CpuRequest        string `json:"cpuRequest" mapstructure:"cpuRequest"`
	CpuLimit          string `json:"cpuLimit" mapstructure:"cpuLimit"`
	MemRequest        string `json:"memRequest" mapstructure:"memRequest"`
	MemLimit          string `json:"memLimit" mapstructure:"memLimit"`
	DockerfileName    string `json:"dockerfileName" mapstructure:"dockerfileName"`
}

func (p *PipelineOptions) ParseJobXml() (jobXml string, err error) {
	_, filePath, _, ok := runtime.Caller(0)
	if !ok {
		return "", err
	}
	rootDir := path.Dir(path.Dir(path.Dir(path.Dir(path.Dir(filePath)))))

	tempFilePath := filepath.Join(rootDir, "template/pipeline_tmp")
	if _, err := os.Stat(tempFilePath); os.IsNotExist(err) {
		return "", err
	}
	file, err := os.ReadFile(tempFilePath)
	if err != nil {
		return "", err
	}

	tmpl, err := template.New("pipeline.xml").Parse(string(file))
	if err != nil {
		return "", err
	}

	buffer := &bytes.Buffer{}
	err = tmpl.Execute(buffer, p)
	if err != nil {
		return "", err
	}

	return buffer.String(), nil
}

type Server struct {
	client *gojenkins.Jenkins
}

func CreateServer(address, user, password string) (*Server, error) {
	ctx := context.Background()
	client, err := gojenkins.CreateJenkins(nil, address, user, password).Init(ctx)
	if err != nil {
		return nil, err
	}
	return &Server{
		client: client,
	}, nil
}

func (s *Server) CreateJob(jobXml, jobName string) error {
	if jobName == "" {
		return errors.New("jenkins job 名称不能为空")
	}
	jobs, err := s.client.GetAllJobNames(context.Background())
	if err != nil {
		return err
	}
	for _, j := range jobs {
		if jobName == j.Name {
			return errors.New("jenkins job 名称重复")
		}
	}

	if _, err := s.client.CreateJob(context.Background(), jobXml, jobName); err != nil {
		return err
	}
	return nil
}
